/*
 *  Copyright (C) Compaq Computer Corporation, 1998, 1999
 *  Copyright (C) Extenex Corporation 2001
 *  Copyright (C) Intrinsyc, Inc., 2002
 *
 * (C) Copyright 2006 Marvell International Ltd.
 * All Rights Reserved
 *
 *  usb_ctl.h
 *
 *  PRIVATE interface used to share info among components of the PXA USB
 *  core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
 *  should use pxa_usb.h.
 *
 *  02-May-2002
 *   Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.h
 *
 */

#ifndef _USB_CTL_H
#define _USB_CTL_H

#include "xllp_clkmgr.h"
#include "pxa_usb.h"

#define CONFIG_CPU_MONAHANS_LV

#define USB_SPEED_FULL  1
#define USB_SPEED_HIGH  2

#define USB_ENDPOINT_XFER_BULK      2
#define USB_ENDPOINT_XFER_INT       3
#define BULK_FIFO_SIZE  (((unsigned)512 + 8)*2) //520??

#ifdef MMU_ENABLE
#define DMA_AREA_START  DDR_UNCACHABLE_BASE
#define DMA_BUF_SIZE    BULK_FIFO_SIZE
#endif

#define DMA_DESC_NUM    100

/* Interrupt mask bits and UDC enable bit */
#define U2DCR_MASK_BITS         (U2DCR_CC | U2DCR_SMAC | U2DCR_EMCE | U2DCR_UDR | U2DCR_UDE)

/*
 * These states correspond to those in the USB specification v1.0
 * in chapter 8, Device Framework.
 */
enum {
    USB_STATE_NOTATTACHED   =0,
    USB_STATE_ATTACHED  =1,
    USB_STATE_POWERED   =2,
    USB_STATE_DEFAULT   =3,
    USB_STATE_ADDRESS   =4,
    USB_STATE_CONFIGURED    =5,
    USB_STATE_SUSPENDED =6
};

struct usb_stats_t {
     unsigned long ep0_fifo_write_failures;
     unsigned long ep0_bytes_written;
     unsigned long ep0_fifo_read_failures;
     unsigned long ep0_bytes_read;
};

struct usb_info_t
{
     char * client_name;
     int state;
     unsigned char address;
     struct usb_stats_t stats;
};

/* in usb_ctl.c */
extern struct usb_info_t usbd_info;

/*
 * Function Prototypes
 */
enum {
    kError      =-1,
    kEvSuspend  =0,
    kEvReset    =1,
    kEvResume   =2,
    kEvAddress  =3,
    kEvConfig   =4,
    kEvDeConfig =5
};
int usbctl_next_state_on_event( int event );
void dump_u2d_reg();

/* endpoint zero */
void ep0_reset(void);
void ep0_int_hndlr(int flag);

/* receiver */
void ep2_state_change_notify( int new_state );
int  ep2_recv(char *buf, int len );
int  ep2_init(int chn);
void ep2_int_hndlr(int flag);
void ep2_reset(void);
void ep2_stall(void);

/* xmitter */
void ep1_state_change_notify( int new_state );
int  ep1_send(char *buf, int len, usb_callback_t callback);
void ep1_reset(void);
int  ep1_init(int chn);
void ep1_int_hndlr(int flag);
void ep1_stall(void);

/* Bulverde USB register's definition */
#define U2DCR        __REG(0x54100000)
#define U2DICR       __REG(0x54100004)
#define U2DISR       __REG(0x5410000C)
#define U2DFNR       __REG(0x54100014)

#define U2DCSR0      __REG(0x54100100)
#define U2DCSRA      __REG(0x54100104)
#define U2DCSRB      __REG(0x54100108)
/* Omit endpoint C~G */

#define U2DBCR0      __REG(0x54100200)
#define U2DBCRA      __REG(0x54100204)
#define U2DBCRB      __REG(0x54100208)
/* Omit endpoint C~G */

#define U2DDR0       __REG(0x54100300)
//?????#define UDCWAKEUP    __REG(0x40F00044)

/* no data reg for endpiont C~G */

#define U2DEPCRA       __REG(0x54100404)
#define U2DEPCRB       __REG(0x54100408)
/* Omit endpoint C~G */

#define U2DEN0          __REG(0x54100504)
#define U2DENA          __REG(0x54100508)
#define U2DENB          __REG(0x5410050C)
/* Omit endpoint C~G */

/* U2DMA registers */
#define U2DMACSR0       __REG(0x54101000)
#define U2DMACSR(x)     __REG(0x54101000 + ((x)<<2)) /* U2DMA Control/Status Register - Channel x */

#define U2DMACR         __REG(0x54101080) /* U2DMA Control Register */
#define U2DMAINT        __REG(0x541010F0) /* U2DMA Interrupt Register */

#define U2DMABR0        __REG(0x54101100) /* U2DMA Branch Register - Channel 0 */
#define U2DMABR(x)      __REG(0x54101100 + (x)<<2) /* U2DMA Branch Register - Channel x */

#define U2DMADADR0      __REG(0x54101200) /* U2DMA Descriptor Address Register - Channel 0 */
#define U2DMADADR(x)    __REG(0x54101200 + (x)*0x10) /* U2DMA Descriptor Address Register - Channel x */
#define U2DMASADR0      __REG(0x54101204) /* U2DMA Source Address Register - Channel 0 */
#define U2DMASADR(x)    __REG(0x54101204 + (x)*0x10) /* U2DMA Source Address Register - Channel x */
#define U2DMATADR0      __REG(0x54101208) /* U2DMA Target Address Register - Channel 0 */
#define U2DMATADR(x)    __REG(0x54101208 + (x)*0x10) /* U2DMA Target Address Register - Channel x */
#define U2DMACMDR0      __REG(0x5410120C) /* U2DMA Command Address Register - Channel 0 */
#define U2DMACMDR(x)    __REG(0x5410120C + (x)*0x10) /* U2DMA Command Address Register - Channel x */


/* USB register bit definitions */
#ifdef CONFIG_CPU_MONAHANS_LV
#define U2DCR_NDC               (1 << 31)       /* NAK During Config */
#endif
#define U2DCR_HSTC_MASK         (0x7 << 28)     /* High Speed Timeout Calibration */
#define U2DCR_HSTC_S            (28)            /* shift */
#ifdef CONFIG_CPU_MONAHANS_LV
#define U2DCR_SPEOREN           (1 << 27)       /* Short Packet EOR INTR generation Enable */
#endif
#define U2DCR_FSTC_MASK         (0x7 << 24)     /* Full Speed Timeout Calibration */
#define U2DCR_FSTC_S            (24)            /* shift */
#define U2DCR_UCLKOVR           (1 << 22)       /* UTM Clock Override */
#define U2DCR_ABP               (1 << 21)       /* Application Bus Power */
#define U2DCR_ADD               (1 << 20)       /* Application Device Disconnect */
#define U2DCR_CC        (1 << 19)   /* Configuration Change */
#define U2DCR_HS        (1 << 18)   /* High Speed USB Detection */
#define U2DCR_SMAC      (1 << 17)   /* Switch Endpoint Memofy to Actuve Configuration */
#define U2DCR_DWRE      (1 << 16)   /* Device Remote Wake-up Feature */
#define U2DCR_ACN       (0xf << 12) /* Active U2D Configuration Number */
#define U2DCR_ACN_S     12              /* shift */
#define U2DCR_AIN       (0xf << 8)  /* Active U2D Interface Number */
#define U2DCR_AIN_S     8               /* shift */
#define U2DCR_AAISN     (0xf << 4)  /* Active U2D Alternate Interface Setting Number */
#define U2DCR_AAISN_S   4               /* shift */
#define U2DCR_EMCE      (1 << 3)    /* Endpoint Memory Configuration Error */
#define U2DCR_UDR       (1 << 2)    /* U2D Resume */
#define U2DCR_UDA       (1 << 1)    /* U2D Active */
#define U2DCR_UDE       (1 << 0)    /* U2D Enable */

#define U2DINT_CC       (1 << 31)   /* Interrupt - Configuration Change */
#define U2DINT_SOF      (1 << 30)   /* Interrupt - SOF */
#define U2DINT_USOF     (1 << 29)   /* Interrupt - micro SOF */
#define U2DINT_RU       (1 << 28)   /* Interrupt - Resume */
#define U2DINT_SU       (1 << 27)   /* Interrupt - Suspend */
#define U2DINT_RS       (1 << 26)   /* Interrupt - Reset */
#define U2DINT_DPE      (1 << 25)   /* Interrupt - Data Packet Error */
#define U2DINT_FIFOERR      (0x4)   /* Interrupt - endpoint FIFO error */
#define U2DINT_PACKETCMP    (0x2)   /* Interrupt - endpoint packet complete */
#define U2DINT_SPACKETCMP   (0x1)   /* Interrupt - endpoint short packet complete */
#define U2DINT(n,intr)  (((intr) & 0x07) << (((n) & 0x07) * 3))

#define U2DCSR0_IPA     (1 << 8)    /* IN Packet Adjusted */
#define U2DCSR0_SA      (1 << 7)    /* SETUP Active */
#define U2DCSR0_RNE     (1 << 6)    /* Receive FIFO Not Empty */
#define U2DCSR0_FST     (1 << 5)    /* Force Stall */
#define U2DCSR0_SST     (1 << 4)    /* Send Stall */
#define U2DCSR0_DME     (1 << 3)    /* DMA Enable */
#define U2DCSR0_FTF     (1 << 2)    /* Flush Transmit FIFO */
#define U2DCSR0_IPR     (1 << 1)    /* IN Packet Ready */
#define U2DCSR0_OPC     (1 << 0)    /* OUT Packet Complete */

#define U2DCSR_BF       (1 << 10)   /* Buffer Full, for OUT eps*/
#define U2DCSR_BE       (1 << 10)   /* Buffer Empty, for IN eps */
#define U2DCSR_DPE      (1 << 9)    /* Data Packet Error, for ISO eps only */
#define U2DCSR_FEF      (1 << 8)    /* Flush Endpoint FIFO */
#define U2DCSR_SP       (1 << 7)    /* Short Packet Control/Status, for OUT eps only, readonly */
#define U2DCSR_BNE      (1 << 6)    /* Buffer Not Empty, for OUT eps */
#define U2DCSR_BNF      (1 << 6)    /* Buffer Not Full, for IN eps */
#define U2DCSR_FST      (1 << 5)    /* Force STALL, write 1 set */
#define U2DCSR_SST      (1 << 4)    /* Sent STALL, write 1 clear */
#define U2DCSR_DME      (1 << 3)    /* DMA Enable */
#define U2DCSR_TRN      (1 << 2)    /* Tx/Rx NAK, write 1 clear */
#define U2DCSR_PC       (1 << 1)    /* Packet Complete, write 1 clear */
#define U2DCSR_FS       (1 << 0)    /* FIFO needs Service */

#define U2DEPCR_EE      (1 << 0)    /* Endpoint Enable */
#define U2DEPCR_BS_MASK (0x3FE)     /* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */

#define U2D_BASE        ((P_XLLP_U2D_REGISTERS_T)(&(__REG(0x54100000)))) //u2DCR)))
#ifndef MFP_BASE
#define MFP_BASE        ((P_XLLP_VUINT32_T)(&(__REG(__REG(0x40E10000))))) //APPS_PAD_BASE))))
#define GPIO_BASE       ((P_XLLP_GPIO_T)(&(__REG(0x40E00000)))) //GPLR0
#define CLK_BASE        ((P_XLLP_CLKMGR_T)(&(__REG(0x41340000))))  //ACCR)))
#endif

#ifdef CONFIG_CPU_MONAHANS_LV
#define U2DOTGCR        __REG(0x54100020) /* U2D OTG Control Register */
#define U2DOTGCR_OTGEN      (1 << 31)   /* On-The-Go Enable */
#define U2DOTGCR_AALTHNP    (1 << 30)   /* A-device Alternate Host Negotiation Protocal Port Support */
#define U2DOTGCR_AHNP       (1 << 29)   /* A-device Host Negotiation Protocal Support */
#define U2DOTGCR_BHNP       (1 << 28)   /* B-device Host Negotiation Protocal Enable */
#define U2DOTGCR_CKAF       (1 << 5)    /* Carkit Mode Alternate Function Select */
#define U2DOTGCR_UTMID      (1 << 4)    /* UTMI Interface Disable */
#define U2DOTGCR_ULAF       (1 << 3)    /* ULPI Mode Alternate Function Select */
#define U2DOTGCR_SMAF       (1 << 2)    /* Serial Mode Alternate Function Select */
#define U2DOTGCR_RTSM       (1 << 1)    /* Return to Synchronous Mode (ULPI Mode) */
#define U2DOTGCR_ULE        (1 << 0)    /* ULPI Wrapper Enable */

#define U2DOTGICR       __REG(0x54100024) /* U2D OTG Interrupt Control Register */
#define U2DOTGISR       __REG(0x54100028) /* U2D OTG Interrupt Status Register */

#define U2DOTGINT_SF        (1 << 17)   /* OTG Set Feature Command Received */
#define U2DOTGINT_SI        (1 << 16)   /* OTG Interrupt */
#define U2DOTGINT_RLS1      (1 << 14)   /* RXCMD Linestate[1] Change Interrupt Rise */
#define U2DOTGINT_RLS0      (1 << 13)   /* RXCMD Linestate[0] Change Interrupt Rise */
#define U2DOTGINT_RID       (1 << 12)   /* RXCMD OTG ID Change Interrupt Rise */
#define U2DOTGINT_RSE       (1 << 11)   /* RXCMD OTG Session End Interrupt Rise */
#define U2DOTGINT_RSV       (1 << 10)   /* RXCMD OTG Session Valid Interrupt Rise */
#define U2DOTGINT_RVV       (1 << 9)    /* RXCMD OTG Vbus Valid Interrupt Rise */
#define U2DOTGINT_RCK       (1 << 8)    /* RXCMD Carkit Interrupt Rise */
#define U2DOTGINT_FLS1      (1 << 6)    /* RXCMD Linestate[1] Change Interrupt Fall */
#define U2DOTGINT_FLS0      (1 << 5)    /* RXCMD Linestate[0] Change Interrupt Fall */
#define U2DOTGINT_FID       (1 << 4)    /* RXCMD OTG ID Change Interrupt Fall */
#define U2DOTGINT_FSE       (1 << 3)    /* RXCMD OTG Session End Interrupt Fall */
#define U2DOTGINT_FSV       (1 << 2)    /* RXCMD OTG Session Valid Interrupt Fall */
#define U2DOTGINT_FVV       (1 << 1)    /* RXCMD OTG Vbus Valid Interrupt Fall */
#define U2DOTGINT_FCK       (1 << 0)    /* RXCMD Carkit Interrupt Fall */

#define U2DOTGUSR       __REG(0x5410002C) /* U2D OTG ULPI Status Register */
#define U2DOTGUSR_LPA       (1 << 31)   /* ULPI Low Power Mode Active */
#define U2DOTGUSR_S6A       (1 << 30)   /* ULPI Serial Mode (6-pin) Active */
#define U2DOTGUSR_S3A       (1 << 29)   /* ULPI Serial Mode (3-pin) Active */
#define U2DOTGUSR_CKA       (1 << 28)   /* ULPI Car Kit Mode Active */
#define U2DOTGUSR_LS1       (1 << 6)    /* RXCMD Linestate 1 Status */
#define U2DOTGUSR_LS0       (1 << 5)    /* RXCMD Linestate 0 Status */
#define U2DOTGUSR_ID        (1 << 4)    /* OTG IDGnd Status */
#define U2DOTGUSR_SE        (1 << 3)    /* OTG Session End Status */
#define U2DOTGUSR_SV        (1 << 2)    /* OTG Session Valid Status */
#define U2DOTGUSR_VV        (1 << 1)    /* OTG Vbus Valid Status */
#define U2DOTGUSR_CK        (1 << 0)    /* Carkit Interrupt Status */

#define U2DOTGUCR       __REG(0x54100030) /* U2D OTG ULPI Control Register */
#define U2DOTGUCR_RUN       (1 << 25)   /* RUN */
#define U2DOTGUCR_RNW       (1 << 24)   /* Read or Write operation */
#define U2DOTGUCR_ADDR      (0x3f << 16)/* Address of the ULPI PHY register to be accessed */
#define U2DOTGUCR_ADDR_S    16          /* shift */
#define U2DOTGUCR_WDATA     (0xff << 8) /* The data for a WRITE command */
#define U2DOTGUCR_WDATA_S   8           /* shift */
#define U2DOTGUCR_RDATA     (0xff << 0) /* The data for a READ command */
#define U2DOTGUCR_RDATA_S   0           /* shift */

#define U2DP3CR         __REG(0x54100034) /* U2D Port 3 Control Register */
#define U2DP3CR_P2SS        (0x3 << 8)  /* Host Port 2 Serial Mode Select */
#define U2DP3CR_P2SS_S      8           /* shift */
#define U2DP3CR_P3SS        (0x7 << 4)  /* Host Port 3 Serial Mode Select */
#define U2DP3CR_P3SS_S      4           /* shift */
#define U2DP3CR_VPVMBEN     (1 << 1)    /* Host Port 3 Vp/Vm Block Enable */
#define U2DP3CR_CFG     (1 << 0)    /* Host Port 3 Configuration */

#endif


#define U2DMACSR_RUN        (1 << 31)       /* Run Bit (read / write) */
#define U2DMACSR_STOPIRQEN  (1 << 29)       /* Stop Interrupt Enable (read / write) */
#define U2DMACSR_EORIRQEN   (1 << 28)       /* End of Receive Interrupt Enable (R/W) */
#define U2DMACSR_EORJMPEN   (1 << 27)       /* Jump to next descriptor on EOR */
#define U2DMACSR_EORSTOPEN  (1 << 26)       /* STOP on an EOR */
#define U2DMACSR_RASIRQEN   (1 << 23)       /* Request After Cnannel Stopped Interrupt Enable */
#define U2DMACSR_MASKRUN    (1 << 22)       /* Mask Run */
#define U2DMACSR_SCEMC      (3 << 18)       /* System Bus Split Completion Error Message Class */
#define U2DMACSR_SCEMI      (0x1f << 13)    /* System Bus Split Completion Error Message Index */
#define U2DMACSR_BUSERRTYPE (7 << 10)       /* PX Bus Error Type */
#define U2DMACSR_EORINTR    (1 << 9)        /* End Of Receive */
#define U2DMACSR_REQPEND    (1 << 8)        /* Request Pending */
#define U2DMACSR_RASINTR    (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */
#define U2DMACSR_STOPINTR   (1 << 3)        /* Stop Interrupt (read only) */
#define U2DMACSR_ENDINTR    (1 << 2)        /* End Interrupt (read / write 1 clear) */
#define U2DMACSR_STARTINTR  (1 << 1)        /* Start Interrupt (read / write 1 clear) */
#define U2DMACSR_BUSERRINTR (1 << 0)        /* Bus Error Interrupt (read / write 1 clear) */
#define U2DMACSR_MASK       0xFFFFFC00


#define U2DMACMDR_LEN   0x07ff      /* length mask (max = 2K - 1) */

#ifdef CONFIG_CPU_MONAHANS_LV
#define ULPI_VENDOR_LOW             0x0
#define ULPI_VENDOR_HIGH            0x1
#define ULPI_PRODUCT_LOW            0x2
#define ULPI_PRODUCT_HIGH           0x3
#define ULPI_FUNCTION_CONTROL           0x4
#define ULPI_FUNCTION_CONTROL_CLEAR         0x6
#define ULPI_FUNCTION_CONTROL_SET       0x5
#define ULPI_INTERFACE_CONTROL          0x7
#define ULPI_INTERFACE_CONTROL_SET      0x8
#define ULPI_INTERFACE_CONTROL_CLEAR        0x9
#define ULPI_OTG_CONTROL            0xA
#define ULPI_OTG_CONTROL_SET            0xB
#define ULPI_OTG_CONTROL_CLEAR          0xC
#define ULPI_INT_RISE               0xD
#define ULPI_INT_RISE_SET           0xE
#define ULPI_INT_RISE_CLEAR             0xF
#define ULPI_INT_FALL               0x10
#define ULPI_INT_FALL_SET           0x11
#define ULPI_INT_FALL_CLEAR             0x12
#define ULPI_INT_STATUS             0x13
#define ULPI_INT_LATCH              0x14
#define ULPI_DEBUG              0x15
#define ULPI_SCRATCH                0x16
#define ULPI_SCRATCH_SET            0x17
#define ULPI_SCRATCH_CLEAR          0x18

#define ULPI_FC_RESET               (1 << 5) /* XCVR Reset */
#define ULPI_FC_SUSPENDM            (1 << 6) /* XCVR SuspendM, Low Power Mode */

#define ULPI_IC_6PIN                (1 << 0) /* XCVR 6 pin mode */
#define ULPI_IC_3PIN                (1 << 1) /* XCVR 3 pin mode */
#define ULPI_IC_CLKSUSPENDM         (1 << 3) /* Active low clock suspend */

#define ULPI_OC_IDPULLUP            (1 << 0) /* ID Pull Up, enable sampling of ID line */
#define ULPI_OC_DPPULLDOWN          (1 << 1) /* Enable the 15K Ohm pull down resistor on D+ */
#define ULPI_OC_DMPULLDOWN          (1 << 2) /* Enable the 15K Ohm pull down resistor on D- */
#define ULPI_OC_DISCHRGVBUS         (1 << 3) /* Discharge Vbus */
#define ULPI_OC_CHRGVBUS            (1 << 4) /* Charge Vbus, for Vbus pulsing SRP */
#define ULPI_OC_DRVVBUS             (1 << 5) /* Drive 5V on Vbus */
#define ULPI_OC_DRVVBUSEXT          (1 << 6) /* Drive Vbus using external supply */

#define ULPI_INT_HOSTDISCON         (1 << 0) /* Host Disconnect */
#define ULPI_INT_VBUSVALID          (1 << 1) /* Vbus Valid */
#define ULPI_INT_SESSIONVALID           (1 << 2) /* Session Valid */
#define ULPI_INT_SESSIONEND         (1 << 3) /* Session End */
#define ULPI_INT_IDGND              (1 << 4) /* current status of IDGND */
#endif

#endif /* _USB_CTL_H */
